home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / widgets-sgi / GLwDrawA.c < prev    next >
C/C++ Source or Header  |  1998-12-15  |  25KB  |  687 lines

  1. /*
  2.  * (c) Copyright 1993, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED 
  4.  * Permission to use, copy, modify, and distribute this software for 
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that 
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission. 
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  * 
  25.  * 
  26.  * US Government Users Restricted Rights 
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  29.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  30.  * clause at DFARS 252.227-7013 and/or in similar or successor
  31.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  32.  * Unpublished-- rights reserved under the copyright laws of the
  33.  * United States.  Contractor/manufacturer is Silicon Graphics,
  34.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  35.  *
  36.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  37.  */
  38.  
  39. /*
  40.  *
  41.  * This file has been slightly modified from the original for use with Mesa
  42.  *
  43.  *     Jeroen van der Zijp
  44.  *
  45.  *     jvz@cyberia.cfdrc.com
  46.  *
  47.  */
  48. #include <X11/IntrinsicP.h>
  49. #include <X11/StringDefs.h>
  50. #include <GL/glx.h>
  51. #include <GL/gl.h>
  52. #ifdef __GLX_MOTIF
  53. #include <Xm/PrimitiveP.h>
  54. #include "GLwMDrawAP.h"
  55. #else 
  56. #include "GLwDrawAP.h"
  57. #endif 
  58. #include <assert.h>
  59. #include <stdio.h>
  60.  
  61. #ifdef __GLX_MOTIF
  62. #define GLwDrawingAreaWidget             GLwMDrawingAreaWidget
  63. #define GLwDrawingAreaClassRec           GLwMDrawingAreaClassRec
  64. #define glwDrawingAreaClassRec           glwMDrawingAreaClassRec
  65. #define glwDrawingAreaWidgetClass        glwMDrawingAreaWidgetClass
  66. #define GLwDrawingAreaRec                GLwMDrawingAreaRec
  67. #endif 
  68.  
  69. #define ATTRIBLIST_SIZE 30
  70.  
  71. #define offset(field) XtOffset(GLwDrawingAreaWidget,glwDrawingArea.field)
  72.  
  73.  
  74. /* forward definitions */
  75. static void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value);
  76. static void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args);
  77. static void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes);
  78. static void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region);
  79. static void Resize(GLwDrawingAreaWidget glw);
  80. static void Destroy(GLwDrawingAreaWidget glw);
  81. static void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams);
  82.  
  83.  
  84.  
  85. static char defaultTranslations[] =
  86. #ifdef __GLX_MOTIF
  87.      "<Key>osfHelp:PrimitiveHelp() \n"
  88. #endif
  89.     "<KeyDown>:   glwInput() \n\
  90.      <KeyUp>:     glwInput() \n\
  91.      <BtnDown>:   glwInput() \n\
  92.      <BtnUp>:     glwInput() \n\
  93.      <BtnMotion>: glwInput() ";
  94.  
  95.  
  96. static XtActionsRec actions[] = {
  97.   {"glwInput",(XtActionProc)glwInput},                /* key or mouse input */
  98.   };
  99.  
  100.  
  101. /*
  102.  * There is a bit of unusual handling of the resources here.
  103.  * Because Xt insists on allocating the colormap resource when it is
  104.  * processing the core resources (even if we redeclare the colormap
  105.  * resource here, we need to do a little trick.  When Xt first allocates
  106.  * the colormap, we allow it to allocate the default one, since we have
  107.  * not yet determined the appropriate visual (which is determined from
  108.  * resources parsed after the colormap).  We also let it allocate colors
  109.  * in that default colormap.
  110.  *
  111.  * In the initialize proc we calculate the actual visual.  Then, we
  112.  * reobtain the colormap resource using XtGetApplicationResources in
  113.  * the initialize proc.  If requested, we also reallocate colors in
  114.  * that colormap using the same method.
  115.  */
  116.  
  117. static XtResource resources[] = {
  118.   /* The GLX attributes.  Add any new attributes here */
  119.  
  120.   {GLwNbufferSize, GLwCBufferSize, XtRInt, sizeof (int),
  121.        offset(bufferSize), XtRImmediate, (XtPointer) 0},
  122.   
  123.   {GLwNlevel, GLwCLevel, XtRInt, sizeof (int),
  124.        offset(level), XtRImmediate, (XtPointer) 0},
  125.   
  126.   {GLwNrgba, GLwCRgba, XtRBoolean, sizeof (Boolean),
  127.        offset(rgba), XtRImmediate, (XtPointer) FALSE},
  128.   
  129.   {GLwNdoublebuffer, GLwCDoublebuffer, XtRBoolean, sizeof (Boolean),
  130.        offset(doublebuffer), XtRImmediate, (XtPointer) FALSE},
  131.   
  132.   {GLwNstereo, GLwCStereo, XtRBoolean, sizeof (Boolean),
  133.        offset(stereo), XtRImmediate, (XtPointer) FALSE},
  134.   
  135.   {GLwNauxBuffers, GLwCAuxBuffers, XtRInt, sizeof (int),
  136.        offset(auxBuffers), XtRImmediate, (XtPointer) 0},
  137.   
  138.   {GLwNredSize, GLwCColorSize, XtRInt, sizeof (int),
  139.        offset(redSize), XtRImmediate, (XtPointer) 1},
  140.   
  141.   {GLwNgreenSize, GLwCColorSize, XtRInt, sizeof (int),
  142.        offset(greenSize), XtRImmediate, (XtPointer) 1},
  143.   
  144.   {GLwNblueSize, GLwCColorSize, XtRInt, sizeof (int),
  145.        offset(blueSize), XtRImmediate, (XtPointer) 1},
  146.   
  147.   {GLwNalphaSize, GLwCAlphaSize, XtRInt, sizeof (int),
  148.        offset(alphaSize), XtRImmediate, (XtPointer) 0},
  149.   
  150.   {GLwNdepthSize, GLwCDepthSize, XtRInt, sizeof (int),
  151.        offset(depthSize), XtRImmediate, (XtPointer) 0},
  152.   
  153.   {GLwNstencilSize, GLwCStencilSize, XtRInt, sizeof (int),
  154.        offset(stencilSize), XtRImmediate, (XtPointer) 0},
  155.   
  156.   {GLwNaccumRedSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  157.        offset(accumRedSize), XtRImmediate, (XtPointer) 0},
  158.   
  159.   {GLwNaccumGreenSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  160.        offset(accumGreenSize), XtRImmediate, (XtPointer) 0},
  161.   
  162.   {GLwNaccumBlueSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  163.        offset(accumBlueSize), XtRImmediate, (XtPointer) 0},
  164.   
  165.   {GLwNaccumAlphaSize, GLwCAccumAlphaSize, XtRInt, sizeof (int),
  166.        offset(accumAlphaSize), XtRImmediate, (XtPointer) 0},
  167.   
  168.   /* the attribute list */
  169.   {GLwNattribList, GLwCAttribList, XtRPointer, sizeof(int *),
  170.        offset(attribList), XtRImmediate, (XtPointer) NULL},
  171.  
  172.   /* the visual info */
  173.   {GLwNvisualInfo, GLwCVisualInfo, GLwRVisualInfo, sizeof (XVisualInfo *),
  174.        offset(visualInfo), XtRImmediate, (XtPointer) NULL},
  175.  
  176.   /* miscellaneous resources */
  177.   {GLwNinstallColormap, GLwCInstallColormap, XtRBoolean, sizeof (Boolean),
  178.        offset(installColormap), XtRImmediate, (XtPointer) TRUE},
  179.  
  180.   {GLwNallocateBackground, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
  181.        offset(allocateBackground), XtRImmediate, (XtPointer) FALSE},
  182.  
  183.   {GLwNallocateOtherColors, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
  184.        offset(allocateOtherColors), XtRImmediate, (XtPointer) FALSE},
  185.  
  186.   {GLwNinstallBackground, GLwCInstallBackground, XtRBoolean, sizeof (Boolean),
  187.        offset(installBackground), XtRImmediate, (XtPointer) TRUE},
  188.  
  189.   {GLwNginitCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  190.        offset(ginitCallback), XtRImmediate, (XtPointer) NULL},
  191.  
  192.   {GLwNinputCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  193.        offset(inputCallback), XtRImmediate, (XtPointer) NULL},
  194.  
  195.   {GLwNresizeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  196.        offset(resizeCallback), XtRImmediate, (XtPointer) NULL},
  197.  
  198.   {GLwNexposeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  199.        offset(exposeCallback), XtRImmediate, (XtPointer) NULL},
  200.  
  201.   /* Changes to Motif primitive resources */
  202. #ifdef __GLX_MOTIF
  203.   {XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof (Boolean),
  204.    XtOffset (GLwDrawingAreaWidget, primitive.traversal_on), XmRImmediate,
  205.    (XtPointer)FALSE},
  206.   
  207.   /* highlighting is normally disabled, as when Motif tries to disable
  208.    * highlighting, it tries to reset the color back to the parent's
  209.    * background (usually Motif blue).  Unfortunately, that is in a
  210.    * different colormap, and doesn't work too well.
  211.    */
  212.   {XmNhighlightOnEnter, XmCHighlightOnEnter, XmRBoolean, sizeof (Boolean),
  213.    XtOffset (GLwDrawingAreaWidget, primitive.highlight_on_enter),
  214.    XmRImmediate, (XtPointer) FALSE},
  215.   
  216.   {XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension,
  217.    sizeof (Dimension),
  218.    XtOffset (GLwDrawingAreaWidget, primitive.highlight_thickness),
  219.    XmRImmediate, (XtPointer) 0},
  220. #endif 
  221.   };
  222.  
  223.  
  224. /*
  225. ** The following resources are reobtained using XtGetApplicationResources
  226. ** in the initialize proc.
  227. */
  228.  
  229. /* The colormap */
  230. static XtResource initializeResources[] = {
  231.   /* reobtain the colormap with the new visual */
  232.   {XtNcolormap, XtCColormap, XtRColormap, sizeof(Colormap),
  233.    XtOffset(GLwDrawingAreaWidget, core.colormap),
  234.    XtRCallProc,(XtPointer) createColormap},
  235.   };
  236.  
  237.  
  238. /* reallocate any colors we need in the new colormap */
  239.   
  240. /* The background is obtained only if the allocateBackground resource is TRUE*/
  241. static XtResource backgroundResources[] = {
  242. #ifdef __GLX_MOTIF
  243.   {XmNbackground, XmCBackground,XmRPixel, 
  244.    sizeof(Pixel),XtOffset(GLwDrawingAreaWidget,core.background_pixel),
  245.    XmRString,(XtPointer)"lightgrey"},
  246.    /*XmRCallProc,(XtPointer)_XmBackgroundColorDefault},*/
  247.  
  248.   {XmNbackgroundPixmap,XmCPixmap,XmRXmBackgroundPixmap, 
  249.    sizeof(Pixmap),XtOffset(GLwDrawingAreaWidget,core.background_pixmap),
  250.    XmRImmediate,(XtPointer)XmUNSPECIFIED_PIXMAP},
  251.  
  252. #else
  253.   {XtNbackground,XtCBackground,XtRPixel,sizeof(Pixel),
  254.    XtOffset(GLwDrawingAreaWidget,core.background_pixel),
  255.    XtRString,(XtPointer)"lightgrey"},
  256.    /*XtRString,(XtPointer)"XtDefaultBackground"},*/
  257.  
  258.   {XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap),
  259.    XtOffset(GLwDrawingAreaWidget,core.background_pixmap),
  260.    XtRImmediate,(XtPointer)XtUnspecifiedPixmap},
  261. #endif  
  262.   };
  263.  
  264.  
  265.  
  266. /* The other colors such as the foreground are allocated only if
  267.  * allocateOtherColors are set.  These resources only exist in Motif.
  268.  */
  269. #ifdef __GLX_MOTIF
  270. static XtResource otherColorResources[] = {
  271.   {XmNforeground,XmCForeground,XmRPixel, 
  272.    sizeof(Pixel),XtOffset(GLwDrawingAreaWidget,primitive.foreground),
  273.    XmRString,(XtPointer)"lighgrey"},
  274.    /*XmRCallProc, (XtPointer) _XmForegroundColorDefault},*/
  275.  
  276.   {XmNhighlightColor,XmCHighlightColor,XmRPixel,sizeof(Pixel),
  277.    XtOffset(GLwDrawingAreaWidget,primitive.highlight_color),
  278.    XmRString,(XtPointer)"lightgrey"},
  279.    /*XmRCallProc,(XtPointer)_XmHighlightColorDefault},*/
  280.  
  281.   {XmNhighlightPixmap,XmCHighlightPixmap,XmRPrimHighlightPixmap,
  282.    sizeof(Pixmap),
  283.    XtOffset(GLwDrawingAreaWidget,primitive.highlight_pixmap),
  284.    XmRImmediate,(XtPointer)XmUNSPECIFIED_PIXMAP},
  285.    /*XmRCallProc,(XtPointer)_XmPrimitiveHighlightPixmapDefault},*/
  286.   };
  287. #endif
  288.  
  289.  
  290. #undef offset
  291.  
  292.  
  293. GLwDrawingAreaClassRec glwDrawingAreaClassRec = {
  294.   { /* core fields */
  295. #ifdef __GLX_MOTIF
  296.     /* superclass                */        (WidgetClass) &xmPrimitiveClassRec,
  297.     /* class_name                */        "GLwMDrawingArea",
  298. #else /* not __GLX_MOTIF */
  299.     /* superclass                */        (WidgetClass) &widgetClassRec,
  300.     /* class_name                */        "GLwDrawingArea",
  301. #endif /* __GLX_MOTIF */
  302.     /* widget_size               */        sizeof(GLwDrawingAreaRec),
  303.     /* class_initialize          */        NULL,
  304.     /* class_part_initialize     */        NULL,
  305.     /* class_inited              */        FALSE,
  306.     /* initialize                */        (XtInitProc) Initialize,
  307.     /* initialize_hook           */        NULL,
  308.     /* realize                   */        Realize,
  309.     /* actions                   */        actions,
  310.     /* num_actions               */        XtNumber(actions),
  311.     /* resources                 */        resources,
  312.     /* num_resources             */        XtNumber(resources),
  313.     /* xrm_class                 */        NULLQUARK,
  314.     /* compress_motion           */        TRUE,
  315.     /* compress_exposure         */        TRUE,
  316.     /* compress_enterleave       */        TRUE,
  317.     /* visible_interest          */        TRUE,
  318.     /* destroy                   */        (XtWidgetProc) Destroy,
  319.     /* resize                    */        (XtWidgetProc) Resize,
  320.     /* expose                    */        (XtExposeProc) Redraw,
  321.     /* set_values                */        NULL,
  322.     /* set_values_hook           */        NULL,
  323.     /* set_values_almost         */        XtInheritSetValuesAlmost,
  324.     /* get_values_hook           */        NULL,
  325.     /* accept_focus              */        NULL,
  326.     /* version                   */        XtVersion,
  327.     /* callback_private          */        NULL,
  328.     /* tm_table                  */        defaultTranslations,
  329.     /* query_geometry            */        XtInheritQueryGeometry,
  330.     /* display_accelerator       */        XtInheritDisplayAccelerator,
  331.     /* extension                 */        NULL
  332.   },
  333. #ifdef __GLX_MOTIF /* primitive resources */
  334.   {
  335.     /* border_highlight          */        XmInheritBorderHighlight,
  336.     /* border_unhighlight        */        XmInheritBorderUnhighlight,
  337.     /* translations              */        XtInheritTranslations,
  338.     /* arm_and_activate          */        NULL,
  339.     /* get_resources             */        NULL,
  340.     /* num get_resources         */        0,
  341.     /* extension                 */        NULL,                                
  342.   }
  343. #endif 
  344.   };
  345.  
  346. WidgetClass glwDrawingAreaWidgetClass=(WidgetClass)&glwDrawingAreaClassRec;
  347.  
  348.  
  349.  
  350. static error(Widget w,char* string){
  351.   char buf[100];
  352. #ifdef __GLX_MOTIF
  353.   sprintf(buf,"GLwMDrawingArea: %s\n",string);
  354. #else
  355.   sprintf(buf,"GLwDrawingArea: %s\n",string);
  356. #endif
  357.   XtAppError(XtWidgetToApplicationContext(w),buf);
  358.   }
  359.  
  360.  
  361. static warning(Widget w,char* string){
  362.   char buf[100];
  363. #ifdef __GLX_MOTIF
  364.   sprintf (buf, "GLwMDraw: %s\n", string);
  365. #else
  366.   sprintf (buf, "GLwDraw: %s\n", string);
  367. #endif
  368.   XtAppWarning(XtWidgetToApplicationContext(w), buf);
  369.   }
  370.  
  371.  
  372.  
  373. /* Initialize the attribList based on the attributes */
  374. static void createAttribList(GLwDrawingAreaWidget w){
  375.   int *ptr;
  376.   w->glwDrawingArea.attribList = (int*)XtMalloc(ATTRIBLIST_SIZE*sizeof(int));
  377.   if(!w->glwDrawingArea.attribList){
  378.     error((Widget)w,"Unable to allocate attribute list");
  379.     }
  380.   ptr = w->glwDrawingArea.attribList;
  381.   *ptr++ = GLX_BUFFER_SIZE;
  382.   *ptr++ = w->glwDrawingArea.bufferSize;
  383.   *ptr++ = GLX_LEVEL;
  384.   *ptr++ = w->glwDrawingArea.level;
  385.   if(w->glwDrawingArea.rgba) *ptr++ = GLX_RGBA;
  386.   if(w->glwDrawingArea.doublebuffer) *ptr++ = GLX_DOUBLEBUFFER;
  387.   if(w->glwDrawingArea.stereo) *ptr++ = GLX_STEREO;
  388.   *ptr++ = GLX_AUX_BUFFERS;
  389.   *ptr++ = w->glwDrawingArea.auxBuffers;
  390.   *ptr++ = GLX_RED_SIZE;
  391.   *ptr++ = w->glwDrawingArea.redSize;
  392.   *ptr++ = GLX_GREEN_SIZE;
  393.   *ptr++ = w->glwDrawingArea.greenSize;
  394.   *ptr++ = GLX_BLUE_SIZE;
  395.   *ptr++ = w->glwDrawingArea.blueSize;
  396.   *ptr++ = GLX_ALPHA_SIZE;
  397.   *ptr++ = w->glwDrawingArea.alphaSize;
  398.   *ptr++ = GLX_DEPTH_SIZE;
  399.   *ptr++ = w->glwDrawingArea.depthSize;
  400.   *ptr++ = GLX_STENCIL_SIZE;
  401.   *ptr++ = w->glwDrawingArea.stencilSize;
  402.   *ptr++ = GLX_ACCUM_RED_SIZE;
  403.   *ptr++ = w->glwDrawingArea.accumRedSize;
  404.   *ptr++ = GLX_ACCUM_GREEN_SIZE;
  405.   *ptr++ = w->glwDrawingArea.accumGreenSize;
  406.   *ptr++ = GLX_ACCUM_BLUE_SIZE;
  407.   *ptr++ = w->glwDrawingArea.accumBlueSize;
  408.   *ptr++ = GLX_ACCUM_ALPHA_SIZE;
  409.   *ptr++ = w->glwDrawingArea.accumAlphaSize;
  410.   *ptr++ = None;
  411.   assert((ptr-w->glwDrawingArea.attribList)<ATTRIBLIST_SIZE);
  412.   }
  413.  
  414.  
  415.  
  416. /* Initialize the visualInfo based on the attribute list */
  417. static void createVisualInfo(GLwDrawingAreaWidget w){
  418.   static XVisualInfo *visualInfo;
  419.   assert(w->glwDrawingArea.attribList);
  420.   w->glwDrawingArea.visualInfo=glXChooseVisual(XtDisplay(w),XScreenNumberOfScreen(XtScreen(w)),w->glwDrawingArea.attribList);
  421.   if(!w->glwDrawingArea.visualInfo) error((Widget)w,"requested visual not supported");
  422.   }
  423.  
  424.  
  425.  
  426. /* Initialize the colormap based on the visual info.
  427.  * This routine maintains a cache of visual-infos to colormaps.  If two
  428.  * widgets share the same visual info, they share the same colormap.
  429.  * This function is called by the callProc of the colormap resource entry.
  430.  */
  431. static void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value){
  432.   static struct cmapCache { Visual *visual; Colormap cmap; } *cmapCache;
  433.   static int cacheEntries=0;
  434.   static int cacheMalloced=0;
  435.   register int i;
  436.     
  437.   assert(w->glwDrawingArea.visualInfo);
  438.  
  439.   /* see if we can find it in the cache */
  440.   for(i=0; i<cacheEntries; i++){
  441.     if(cmapCache[i].visual==w->glwDrawingArea.visualInfo->visual){
  442.       value->addr=(XtPointer)(&cmapCache[i].cmap);
  443.       return;
  444.       }
  445.     }
  446.  
  447.   /* not in the cache, create a new entry */
  448.   if(cacheEntries >= cacheMalloced){
  449.     /* need to malloc a new one.  Since we are likely to have only a
  450.      * few colormaps, we allocate one the first time, and double
  451.      * each subsequent time.
  452.      */
  453.     if(cacheMalloced==0){
  454.       cacheMalloced=1;
  455.       cmapCache=(struct cmapCache*)XtMalloc(sizeof(struct cmapCache));
  456.       }
  457.     else{
  458.       cacheMalloced<<=1;
  459.       cmapCache=(struct cmapCache*)XtRealloc((char*)cmapCache,sizeof(struct cmapCache)*cacheMalloced);
  460.       }
  461.     }
  462.        
  463.   cmapCache[cacheEntries].cmap=XCreateColormap(XtDisplay(w),
  464.                                                RootWindow(XtDisplay(w),
  465.                                                w->glwDrawingArea.visualInfo->screen),
  466.                                                w->glwDrawingArea.visualInfo->visual,
  467.                                                AllocNone);
  468.   cmapCache[cacheEntries].visual=w->glwDrawingArea.visualInfo->visual;
  469.   value->addr=(XtPointer)(&cmapCache[cacheEntries++].cmap);
  470.   }
  471.  
  472.  
  473.  
  474. static void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args){
  475.  
  476.   /* fix size */
  477.   if(req->core.width==0) neww->core.width=100;
  478.   if(req->core.height==0) neww->core.width=100;
  479.  
  480.   /* create the attribute list if needed */
  481.   neww->glwDrawingArea.myList=FALSE;
  482.   if(neww->glwDrawingArea.attribList==NULL){
  483.     neww->glwDrawingArea.myList=TRUE;
  484.     createAttribList(neww);
  485.     }
  486.  
  487.   /* Gotta have it */
  488.   assert(neww->glwDrawingArea.attribList);
  489.  
  490.   /* determine the visual info if needed */
  491.   neww->glwDrawingArea.myVisual=FALSE;
  492.   if(neww->glwDrawingArea.visualInfo==NULL){
  493.     neww->glwDrawingArea.myVisual=TRUE;
  494.     createVisualInfo(neww);
  495.     }
  496.  
  497.   /* Gotta have that too */
  498.   assert(neww->glwDrawingArea.visualInfo);
  499.  
  500.   neww->core.depth=neww->glwDrawingArea.visualInfo->depth;
  501.  
  502.   /* Reobtain the colormap and colors in it using XtGetApplicationResources*/
  503.   XtGetApplicationResources((Widget)neww,neww,initializeResources,XtNumber(initializeResources),args,*num_args);
  504.  
  505.   /* obtain the color resources if appropriate */
  506.   if(req->glwDrawingArea.allocateBackground){
  507.     XtGetApplicationResources((Widget)neww,neww,backgroundResources,XtNumber(backgroundResources),args,*num_args);
  508.     }
  509.  
  510. #ifdef __GLX_MOTIF
  511.   if(req->glwDrawingArea.allocateOtherColors){
  512.     XtGetApplicationResources((Widget)neww,neww,otherColorResources,XtNumber(otherColorResources),args,*num_args);
  513.     }
  514. #endif 
  515.   }
  516.  
  517.  
  518.  
  519. static void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes){
  520.   register GLwDrawingAreaWidget glw=(GLwDrawingAreaWidget)w;
  521.   GLwDrawingAreaCallbackStruct cb;
  522.   Widget parentShell;
  523.   Status status;
  524.   Window windows[2],*windowsReturn,*windowList;
  525.   int countReturn,i;
  526.    
  527.   /* if we haven't requested that the background be both installed and
  528.    * allocated, don't install it.
  529.    */
  530.   if(!(glw->glwDrawingArea.installBackground && glw->glwDrawingArea.allocateBackground)){
  531.     *valueMask&=~CWBackPixel;
  532.     }
  533.  
  534.   XtCreateWindow(w,(unsigned int)InputOutput,glw->glwDrawingArea.visualInfo->visual,*valueMask,attributes);
  535.  
  536.   /* if appropriate, call XSetWMColormapWindows to install the colormap */
  537.   if(glw->glwDrawingArea.installColormap){
  538.  
  539.     /* Get parent shell */
  540.     for(parentShell=XtParent(w); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell));
  541.  
  542.     if(parentShell && XtWindow(parentShell)){
  543.  
  544.       /* check to see if there is already a property */
  545.       status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn);
  546.             
  547.       /* if no property, just create one */
  548.       if(!status){
  549.         windows[0]=XtWindow(w);
  550.         windows[1]=XtWindow(parentShell);
  551.         XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windows,2);
  552.         }
  553.  
  554.       /* there was a property, add myself to the beginning */
  555.       else{
  556.         windowList=(Window *)XtMalloc((sizeof(Window))*(countReturn+1));
  557.         windowList[0]=XtWindow(w);
  558.         for(i=0; i<countReturn; i++) windowList[i+1]=windowsReturn[i];
  559.         XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowList,countReturn+1);
  560.         XtFree((char*)windowList);
  561.         XtFree((char*)windowsReturn);
  562.         }
  563.       }
  564.     else{
  565.       warning(w,"Could not set colormap property on parent shell");
  566.       }
  567.     }
  568.  
  569.   /* Invoke callbacks */
  570.   cb.reason=GLwCR_GINIT;
  571.   cb.event=NULL;
  572.   cb.width=glw->core.width;
  573.   cb.height=glw->core.height;
  574.   XtCallCallbackList((Widget)glw,glw->glwDrawingArea.ginitCallback,&cb);
  575.   }
  576.  
  577.  
  578.  
  579. static void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region){
  580.   GLwDrawingAreaCallbackStruct cb;
  581.   XtCallbackList cblist;
  582.   if(!XtIsRealized((Widget)w)) return;
  583.   cb.reason=GLwCR_EXPOSE;
  584.   cb.event=event;
  585.   cb.width=w->core.width;
  586.   cb.height=w->core.height;
  587.   XtCallCallbackList((Widget)w,w->glwDrawingArea.exposeCallback,&cb);
  588.   }
  589.  
  590.  
  591.  
  592. static void Resize(GLwDrawingAreaWidget glw){
  593.   GLwDrawingAreaCallbackStruct cb;
  594.   if(!XtIsRealized((Widget)glw)) return;
  595.   cb.reason=GLwCR_RESIZE;
  596.   cb.event=NULL;
  597.   cb.width=glw->core.width;
  598.   cb.height=glw->core.height;
  599.   XtCallCallbackList((Widget)glw,glw->glwDrawingArea.resizeCallback,&cb);
  600.   }
  601.  
  602.  
  603.  
  604. static void Destroy(GLwDrawingAreaWidget glw){
  605.   Window *windowsReturn;
  606.   Widget parentShell;
  607.   Status status;
  608.   int countReturn;
  609.   register int i;
  610.  
  611.   if(glw->glwDrawingArea.myList && glw->glwDrawingArea.attribList){
  612.     XtFree((XtPointer)glw->glwDrawingArea.attribList);
  613.     }
  614.  
  615.   if(glw->glwDrawingArea.myVisual && glw->glwDrawingArea.visualInfo){
  616.     XtFree((XtPointer)glw->glwDrawingArea.visualInfo);
  617.     }
  618.  
  619.   /* if my colormap was installed, remove it */
  620.   if(glw->glwDrawingArea.installColormap){
  621.  
  622.     /* Get parent shell */
  623.     for(parentShell=XtParent(glw); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell));
  624.  
  625.     if(parentShell && XtWindow(parentShell)){
  626.  
  627.       /* make sure there is a property */
  628.       status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn);
  629.             
  630.       /* if no property, just return.  If there was a property, continue */
  631.       if(status){
  632.  
  633.         /* search for a match */
  634.         for(i=0; i<countReturn; i++){
  635.           if(windowsReturn[i]==XtWindow(glw)){
  636.  
  637.             /* we found a match, now copy the rest down */
  638.             for(i++; i<countReturn; i++){ windowsReturn[i-1]=windowsReturn[i]; }
  639.  
  640.             XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowsReturn,countReturn-1);
  641.             break; 
  642.             }
  643.           }
  644.         XtFree((char *)windowsReturn);
  645.         }
  646.       }
  647.     }
  648.   }
  649.  
  650.  
  651.  
  652. /* Action routine for keyboard and mouse events */
  653. static void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams){
  654.   GLwDrawingAreaCallbackStruct cb;
  655.   cb.reason=GLwCR_INPUT;
  656.   cb.event=event;
  657.   cb.width=glw->core.width;
  658.   cb.height=glw->core.height;
  659.   XtCallCallbackList((Widget)glw,glw->glwDrawingArea.inputCallback,&cb);
  660.   }
  661.  
  662.  
  663. #ifdef __GLX_MOTIF
  664.  
  665. /* Create routine */
  666. Widget GLwCreateMDrawingArea(Widget parent, char *name,ArgList arglist,Cardinal argcount){
  667.   return XtCreateWidget(name,glwMDrawingAreaWidgetClass, parent, arglist,argcount);
  668.   }
  669.  
  670. #endif
  671.  
  672.  
  673. #ifndef __GLX_MOTIF
  674.  
  675. /* Make context current */
  676. void GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx){
  677.   glXMakeCurrent(XtDisplay(w),XtWindow(w),ctx);
  678.   }
  679.  
  680.  
  681. /* Swap buffers convenience function */
  682. void GLwDrawingAreaSwapBuffers(Widget w){
  683.   glXSwapBuffers(XtDisplay(w),XtWindow(w));
  684.   }
  685.  
  686. #endif
  687.